﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MockDataTransferObject;
using MockCommon;
using System.Data;
using System.Data.SqlClient;
using System.Collections.ObjectModel;

namespace MockDataAccess
{
    public class TimesheetDataAccess : BaseDataAccess<Timesheet>
    {
        private Collection<SqlParameter> _parameters;

        /// <summary>
        /// Initializes a new instance of the <see cref="TimesheetDataAccess"/> class.
        /// </summary>
        public TimesheetDataAccess()
            : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TimesheetDataAccess"/> class.
        /// </summary>
        /// <param name="isFake">if set to <c>true</c> [is fake].</param>
        public TimesheetDataAccess(bool isFake)
            : base(isFake)
        {
        }

        #region Is
        /// <summary>
        /// Determines whether [is exist status name] [the specified status name].
        /// </summary>
        /// <param name="statusName">Name of the status.</param>
        /// <param name="timesheetId">The timesheet id.</param>
        /// <returns>
        ///   <c>true</c> if [is exist status name] [the specified status name]; otherwise, <c>false</c>.
        /// </returns>
        public bool IsExistStatusName(string statusName, Guid timesheetId)
        {
            _parameters = new Collection<SqlParameter>();
            _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterStatusName, Value = statusName });
            _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterTimesheetId, Value = timesheetId });
            object result = ExecuteQueryAsScalar(Constant.TimesheetGetTimesheetIdByStatusName, _parameters);
            if (result != null)
            {
                return true;
            }
            return false;
        }
        #endregion

        #region Get
        /// <summary>
        /// Gets the name of the by client user name and status.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="statusName">Name of the status.</param>
        /// <returns></returns>
        public Collection<Timesheet> GetByClientUserNameAndStatusName(string userName, string statusName)
        {
            _parameters = new Collection<SqlParameter>();
            _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterUserName, Value = userName });
            _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterStatusName, Value = statusName });
            DataTable dataTable = ExecuteQueryAsDataTable(Constant.TimesheetGetByClientUserNameAndStatusName, _parameters);
            Collection<AbstractEntity> entities = ConvertToList(dataTable, typeof(Timesheet));
            return new Collection<Timesheet>(entities.Cast<Timesheet>().ToList());
        }

        /// <summary>
        /// Gets the name of the by contractor user.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <returns></returns>
        public Collection<Timesheet> GetByContractorUserName(string userName)
        {
            try
            {
                _parameters = new Collection<SqlParameter>();
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterUserName, Value = userName });
                DataTable tableTimeSheetByUserName = ExecuteQueryAsDataTable(Constant.TimesheetGetByContractorUserName, _parameters);
                Collection<AbstractEntity> entities = ConvertToList(tableTimeSheetByUserName, typeof(Timesheet));
                return new Collection<Timesheet>(entities.Cast<Timesheet>().ToList());
            }
            catch (ArgumentException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (InvalidCastException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
        }

        /// <summary>
        /// Gets the by filter.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="statusId">The status id.</param>
        /// <returns></returns>
        public Collection<Timesheet> GetByFilter(string userName, Guid statusId)
        {
            try
            {
                _parameters = new Collection<SqlParameter>();
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterUserName, Value = userName });
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterStatusId, Value = statusId });
                DataTable result = ExecuteQueryAsDataTable(Constant.TimesheetGetByFilter, _parameters);
                Collection<AbstractEntity> entities = ConvertToList(result, typeof(Timesheet));
                return new Collection<Timesheet>(entities.Cast<Timesheet>().ToList());
            }
            catch (ArgumentException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (InvalidCastException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
        }

        /// <summary>
        /// Gets the by filter range.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="statusId">The status id.</param>
        /// <param name="fromDate">From date.</param>
        /// <param name="toDate">To date.</param>
        /// <returns></returns>
        public Collection<Timesheet> GetByFilterRange(string userName, Guid statusId, DateTime fromDate, DateTime toDate)
        {
            try
            {
                _parameters = new Collection<SqlParameter>();
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterUserName, Value = userName });
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterStatusId, Value = statusId });
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterFromDate, Value = fromDate });
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterToDate, Value = toDate });
                DataTable result = ExecuteQueryAsDataTable(Constant.TimesheetGetByFilterRange, _parameters);
                Collection<AbstractEntity> entities = ConvertToList(result, typeof(Timesheet));
                return new Collection<Timesheet>(entities.Cast<Timesheet>().ToList());
            }
            catch (ArgumentException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (InvalidCastException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
        }

        /// <summary>
        /// Gets the by contractor id.
        /// </summary>
        /// <param name="contractorId">The contractor id.</param>
        /// <returns></returns>
        public Collection<Timesheet> GetByContractorId(Guid contractorId)
        {
            try
            {
                _parameters = new Collection<SqlParameter>();
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterContractorId, Value = contractorId });
                DataTable table = ExecuteQueryAsDataTable(Constant.TimesheetGetByContractorId, _parameters);
                Collection<AbstractEntity> entities = ConvertToList(table, typeof(Timesheet));

                return new Collection<Timesheet>(entities.Cast<Timesheet>().ToList());
            }
            catch (ArgumentException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (InvalidCastException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
        }
        #endregion
    }
}

